import asyncio

async def delay(n):
    print(f'delay for {n} seconds')
    await asyncio.sleep(n)
    print(f'delay for {n} seconds done')
    return n

async def hello_every_second():
    for i in range(5):
        await asyncio.sleep(1)
        print("I'm running other code while I'm waiting")


async def main():
    # 在你的代码中，`first_delay` 和 `second_delay` 是通过 `asyncio.create_task()` 创建的任务。
    # 当你调用 `asyncio.create_task()`，传入的协程会被立即调度在事件循环中执行，而不需要等待当前协程（在这个例子中是 `main` 函数）完成。
    # 因此，当 `main` 函数执行到 `await hello_every_second()` 时，`first_delay` 和 `second_delay` 已经开始执行了。
    # `await hello_every_second()` 会挂起 `main` 函数并等待 `hello_every_second` 完成，
    # 但这并不会阻止事件循环执行其他的任务，如 `first_delay` 和 `second_delay`。
    # 这就是为什么 `first_delay` 和 `second_delay` 可以并发执行， 并且可能立刻执行了。
    first_delay = asyncio.create_task(delay(3))
    second_delay = asyncio.create_task(delay(3))
    await hello_every_second()
    await first_delay
    await second_delay

    # 必须等到 hello_every_second() 执行完毕， 才会执行下面的代码
    print("main done")
    
    # hello_every_second() range 5 会输出
    # delay for 3 seconds
    # delay for 3 seconds
    # I'm running other code while I'm waiting
    # I'm running other code while I'm waiting
    # delay for 3 seconds done
    # delay for 3 seconds done
    # I'm running other code while I'm waiting
    # I'm running other code while I'm waiting
    # I'm running other code while I'm waiting
    # main done

async def main_v2():
    await hello_every_second()
    # 必须等待 hello_every_second() 执行完毕， 才会执行下面的代码

    first_delay = asyncio.create_task(delay(3))
    second_delay = asyncio.create_task(delay(3))
    await first_delay
    await second_delay

    # I'm running other code while I'm waiting
    # I'm running other code while I'm waiting
    # I'm running other code while I'm waiting
    # I'm running other code while I'm waiting
    # I'm running other code while I'm waiting
    # delay for 3 seconds
    # delay for 3 seconds
    # delay for 3 seconds done
    # delay for 3 seconds done

asyncio.run(main())